/*
 * 题目描述：给出一个图，找到某个节点，以它为根的时候，树的长度最长，如果有多个按照升序输出
 *
 * 输入：N 节点数目
 *      N-1行 连接边
 *
 * 输出：从小到大的顶点
 *
 * 思路：先通过dfs判断连同分量的个数，若分量为1，则使用Floyd-warshal算法计算根的长度，遍历输出最大的
 *
 * 坑：因为N<=10000，有个测试点使用的是大数据，如果使用邻接矩阵那么会报内存超限
 */
#include <iostream>
#include <cstdio>
#include <climits>
#include <stack>
using namespace std;

int **graph;
int nodeNum;
int maxDepth = 0;
int cmpt = 0;
int *record;
void dfs(int start, int *record){
    stack<int> s;
    s.push(start);
    while(!s.empty()){
        start = s.top();
        s.pop();
        record[start] = 1;
        for (int i = 1; i <= nodeNum; i++) {
            if (record[i] == 0 && graph[start][i] != 0 && graph[start][i] != INT_MAX / 2) {
                s.push(i);
                record[i] = 1;
            }
        }
    }
}

int isFinished(int *record){
    for (int i = 1; i <= nodeNum; i++) {
        if (record[i] == 0) {
            return i;
        }
    }
    return -1;
}

int **create2DArr(int size, int init){
    int **arr = new int *[nodeNum+1];
    for (int i = 1; i <= nodeNum; i++) {
        arr[i] = new int[nodeNum + 1];
        for (int j = 1; j <= nodeNum; j++) {
            if (i == j) {
                arr[i][j] = 0;
            }else{
                arr[i][j] = init;
            }
        }
    }
    return arr;
}

void print(int **arr){
    for (int i = 1; i <= nodeNum; i++) {
        for (int j = 1; j <= nodeNum; j++) {
            cout << i << " " << j << " " << arr[i][j] << endl;
        }
    }
}

int main() {
    cin >> nodeNum;
    graph = create2DArr(nodeNum, INT_MAX/2);
    int j,k;
    for (int i = 1; i < nodeNum; i++) {
        cin >> j >> k;
        graph[j][k] = graph[k][j] = 1;
    }
    record = new int[nodeNum+1]();
    int start = 0;
    while((start = isFinished(record))!=-1){
        cmpt++;
        dfs(start, record);
    }
    if (cmpt != 1) {
        printf("Error: %d components", cmpt);
    }else{
        int **dist = graph;
        int max = 0;
        for (int k = 1; k <= nodeNum; k++) {
            for (int i = 1; i <= nodeNum; i++) {
                for (int j = 1; j <= nodeNum; j++) {
                    if(dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                        if(dist[i][j] > max){
                            max = dist[i][j];
                        }
                    }
                }
            }
        }
        for (int i = 1; i <= nodeNum; i++) {
            record[i] = 0;
        }
        for (int i = 1; i <= nodeNum; i++) {
            for (int j = 1; j <= nodeNum; j++) {
                if (dist[i][j] == max) {
                    record[i] = record[j] = 1;
                }
            }
        }
        for (int i = 1; i <= nodeNum; i++) {
            if (record[i] == 1) {
                cout << i << endl;
            }
        }
    }
    return 0;
}

//正确
/*
 * 题目描述：给出一个图，找到某个节点，以它为根的时候，树的长度最长，如果有多个按照升序输出
 *
 * 输入：N 节点数目
 *      N-1行 连接边
 *
 * 输出：从小到大的顶点
 *
 * 思路：先通过并查集判断连同分量的个数，若分量为1，则使用BFS遍历计算根的长度，遍历输出最大的
 *
 * 坑：因为N<=10000，有个测试点使用的是大数据，如果使用邻接矩阵那么会报内存超限
 */

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#define MAX_SIZE 10001
using namespace std;

int *father;
int *sz;
vector<int> *graph;
int *dist;
int N;
int cnt;

void makeSet(){
    for (int i = 1; i <= N; i++) {
        father[i] = i;
        sz[i] = 1;
    }
}

int findSet(int x){
    while (x != father[x]) {
        father[x] = father[father[x]];
        x = father[x];
    }
    return x;
}

int unionSet(int x, int y){
    x = findSet(x);
    y = findSet(y);
    if (x == y) {
        return 0;
    }else if(sz[x] > sz[y]){
        father[y] = x;
        sz[x] += sz[y];
    }else{
        father[x] = y;
        sz[y] += sz[x];
    }
    return 1;
}

int bfs(int start){
    int maxDepth = 0;
    int depth = 0;
    int *vst = new int[N+1]();
    queue<int> q;
    q.push(start);
    vst[start] = true;
    while (!q.empty()) {
        start = q.front();
        q.pop();
        depth = vst[start];
        bool isFind = false;
        for (int i = 0; i < graph[start].size(); i++) {
            if(vst[graph[start][i]]==0){
                isFind = true;
                q.push(graph[start][i]);
                //记录节点深度
                vst[graph[start][i]] = depth + 1;
            }
        }
        if(isFind){
            depth++;
            if (depth > maxDepth) {
                maxDepth = depth;
            }
        }
    }
    delete vst;
    return maxDepth;
}

int main(){
    cin >> N;
    cnt = N;
    father = new int[N + 1]();
    sz = new int[N + 1]();
    graph = new vector<int>[N + 1]();
    dist = new int[N + 1]();
    makeSet();
    int j, k;
    for (int i = 1; i < N; i++) {
        cin >> j >> k;
        cnt-=unionSet(j, k);
        graph[j].push_back(k);
        graph[k].push_back(j);
    }
    if(cnt!=1){
        printf("Error: %d components", cnt);
    }else{
        int max = 0;
        for (int i = 1; i <= N; i++) {
            dist[i] = bfs(i);
            if (dist[i] > max) {
                max = dist[i];
            }
        }
        for (int i = 1; i <= N; i++) {
            if (dist[i] == max) {
                cout << i << endl;
            }
        }
    }
}